package com.dng.book.interceptor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.dng.book.common.Result;
import com.dng.book.service.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Token拦截器
 *
 * @author dng
 * @since 2024-01-01
 */
@Slf4j
@Component
public class TokenInterceptor implements HandlerInterceptor {

    @Resource
    private TokenService tokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取请求路径
        String requestURI = request.getRequestURI();
        log.info("Token拦截器 - 请求路径: {}", requestURI);

        // 不需要验证Token的路径
        if (isExcludedPath(requestURI)) {
            log.info("Token拦截器 - 跳过验证: {}", requestURI);
            return true;
        }

        // 获取Token
        String token = getTokenFromRequest(request);
        log.info("Token拦截器 - 请求路径: {}, Token: {}", requestURI, token);
        if (StrUtil.isBlank(token)) {
            log.warn("Token拦截器 - Token为空: {}", requestURI);
            writeErrorResponse(response, "Token不能为空");
            return false;
        }

        // 验证Token
        String username = tokenService.validateToken(token);
        if (StrUtil.isBlank(username)) {
            log.warn("Token拦截器 - Token验证失败: {}, Token: {}", requestURI, token);
            writeErrorResponse(response, "Token无效或已过期");
            return false;
        }

        // 将用户名存储到请求属性中，供后续使用
        request.setAttribute("currentUser", username);
        log.info("Token拦截器 - 验证成功: {}, 用户名: {}", requestURI, username);

        return true;
    }

    /**
     * 判断是否为不需要验证Token的路径
     */
    private boolean isExcludedPath(String requestURI) {
        // 登录相关接口
        if (requestURI.contains("/user/login")) {
            return true;
        }
        
        // 验证码相关接口
        if (requestURI.contains("/captcha")) {
            return true;
        }
        
        // 短信相关接口
        if (requestURI.contains("/sendSms") || requestURI.contains("/resetPassword")) {
            return true;
        }
        
        // 测试接口
        if (requestURI.contains("/test/")) {
            return true;
        }
        
        // 健康检查接口
        if (requestURI.contains("/actuator/")) {
            return true;
        }
        
        // API文档接口
        if (requestURI.contains("/swagger-ui/") || requestURI.contains("/v3/api-docs")) {
            return true;
        }
        
        return false;
    }

    /**
     * 从请求中获取Token
     */
    private String getTokenFromRequest(HttpServletRequest request) {
        // 优先从请求头中获取
        String token = request.getHeader("Authorization");
        if (StrUtil.isNotBlank(token)) {
            // 支持Bearer格式和直接token格式
            if (token.startsWith("Bearer ")) {
                return token.substring(7);
            } else {
                return token;
            }
        }
        
        // 从请求参数中获取
        token = request.getParameter("token");
        if (StrUtil.isNotBlank(token)) {
            return token;
        }
        
        return null;
    }

    /**
     * 写入错误响应
     */
    private void writeErrorResponse(HttpServletResponse response, String message) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        
        Result<?> result = Result.error(401, message);
        String jsonResponse = JSONUtil.toJsonStr(result);
        
        try (PrintWriter writer = response.getWriter()) {
            writer.write(jsonResponse);
            writer.flush();
        }
    }
} 